package code;

import java.util.Calendar;
import java.util.TimeZone;

import net.rim.device.api.util.DateTimeUtilities;

public class LunarCalendar
{
	final static String[] nStr1 = {"日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
	final static String[] nStr2 = {"初", "十", "廿", "卅", "□"};
	final static long[] lunarInfo=new long[] {0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,
									          0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,
									          0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,0x06ca0,0x0b550,0x15355,0x04da0,0x0a5d0,0x14573,0x052d0,0x0a9a8,0x0e950,0x06aa0,
									          0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b5a0,0x195a6,
									          0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,
									          0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,
									          0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,
									          0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0};

	//获取农历某年的总天数
	final public static int lYearDays(int y)
	{
        int sum = 348;
        
        for(int i=0x8000; i>0x8; i>>=1) {sum+=(lunarInfo[y-1900] & i)!=0 ? 1 : 0;}
        
        return sum+leapDays(y);
	}
	
	//获取农历某年闰月的天数
	final public static int leapDays(int y)
	{
		if(leapMonth(y)!=0)
		{
			return (lunarInfo[y-1900] & 0x10000)!=0 ? 30 : 29;
		} else {
			return 0;
		}
	}

	//获取农历某的闰月有哪几个，返回值为 1到12，没闰月返回 0
	final public static int leapMonth(int y)
	{
		return (int)(lunarInfo[y-1900] & 0xf);
	}

	//获取农历某年某月的总天数
	final public static int monthDays(int y,int m)
	{
        if((lunarInfo[y-1900]&(0x10000>>m))==0)
        {
        	return 29;
        } else {
        	return 30;
        }
	}

	//传出y年m月d日对应的农历 (0:year, 1:month, 2:day, 3:isLeap)
	final public static long[] Lunar(int y,int m,int d)
	{
        long[] nongDate = new long[4];
        int i, temp=0, leap=0;
        Calendar objDate=Calendar.getInstance(TimeZone.getDefault());
        Calendar baseDate=Calendar.getInstance(TimeZone.getDefault());

        objDate.set(Calendar.YEAR, y);
        objDate.set(Calendar.MONTH, m-1);
        objDate.set(Calendar.DAY_OF_MONTH, d);

        baseDate.set(Calendar.YEAR, 1900);
        baseDate.set(Calendar.MONTH, 0);
        baseDate.set(Calendar.DAY_OF_MONTH, 31);
        
        long offset=(objDate.getTime().getTime()-baseDate.getTime().getTime())/DateTimeUtilities.ONEDAY;
        
        for(i=1900; i<2050 && offset>0; i++)
        {
        	temp=lYearDays(i);
        	offset-=temp;
        }

        if(offset<0) {offset+=temp; i--;}

        nongDate[0] = i;

        leap = leapMonth(i); //闰哪个月
        nongDate[3] = 0;

        for(i=1; i<13 && offset>0; i++) {
        	//闰月
        	if(leap>0 && i==(leap+1) && nongDate[3]==0)
        	{
        		--i;
        		nongDate[3] = 1;
        		temp = leapDays((int)nongDate[0]);
        	} else {
        		temp = monthDays((int) nongDate[0], i);
        	}

        	//解除闰月
        	if(nongDate[3]==1 && i==(leap+1)) {nongDate[3] = 0;}

        	offset -= temp;
        }

        if(offset==0 && leap>0 && i==leap+1)
        {
        	if(nongDate[3]==1)
        	{
        		nongDate[3] = 0;
        	} else {
        		nongDate[3] = 1;
        		--i;
        	}
        }

        if(offset<0) {offset += temp; --i;}

        nongDate[1] = i;
        nongDate[2] = offset + 1;

        return nongDate;
	}

	public static String cDay(int day)
	{
		String s="";

		switch(day)
		{
			case 10:
				s = "初十"; break;
			case 20:
				s = "二十"; break;
			case 30:
				s = "三十"; break;
			default:
				s = nStr2[(int) Math.floor(day/10)];
				s += nStr1[day%10];
		}
		
		return(s);
	}	
}